#include <stdio.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT	9000

static void
error(char *msg)
{
	fputs(strerror(errno), stderr);
	fputs(": ", stderr);
	fputs(msg, stderr);
	fputc('\n', stderr);
	exit(1);
}

int main(int argc, char **argv)
{
    int z;		//exit status code
    size_t x;
    char *srvr_addr = NULL;	//server string address

    struct sockaddr_in inet_clnt;	// client socket address
    struct sockaddr_in inet_srvr;	// server socket address

    int len_inet;			// size of socket address
    int s;				// socket fd

    char dgram[512];			// datagram to be sent

    if ( argc >= 2) {
	srvr_addr = argv[1];
    } else {
	fprintf(stderr, "ERROR: provider server address");
	exit(1);
    }

    // initialize server socket address
    memset(&inet_srvr, 0, sizeof(inet_srvr));
    inet_srvr.sin_family = AF_INET;
    inet_srvr.sin_port = htons(PORT);
    if ( inet_aton(srvr_addr, &inet_srvr.sin_addr) == -1 )
	error("inet_aton()");

    len_inet = sizeof(inet_srvr);

    // create udp socket
    s = socket(AF_INET, SOCK_DGRAM, 0);
    if ( s == -1 )
	error("socket()");

    for ( ; ; ) {
	//promt user for a date format string
	fputs("\nEnter format string: ", stdout);
	if ( ! fgets(dgram, sizeof(dgram), stdin) ) {
	    error("fgets()");
	    break;
	}

	z = strlen(dgram);
	if ( z > 0 && dgram[--z] == '\n' )
	    dgram[z] = 0;
	
	// send formatted sting to the server
	z = sendto(s, dgram, strlen(dgram), 0, (struct sockaddr *) &inet_srvr, len_inet);
	if ( z < 0 )
	    error("sendto()");

	if ( ! strcasecmp(dgram, "QUIT") )
	    break;	//quit

	// wait for responce
	x = sizeof(inet_clnt);
	z = recvfrom(s, dgram, sizeof(dgram), 0, (struct sockaddr *) &inet_clnt, &x);
	if ( z < 0 )
	    error("recvfrom()");
	
	dgram[z] = 0;

	printf("Result from %s port %u : \n\t'%s'\n", inet_ntoa(inet_clnt.sin_addr), (unsigned) ntohs(inet_clnt.sin_port), dgram);
    }

    close(s);

    putchar('\n');

    return 0;
}
